[Git] ブランチを作成する際にcannot lock refと怒られて失敗することがある
こんにちは。サービス部の武田です。
Gitを使用しているとブランチの作成は意識しなくても指が勝手に動くのではないでしょうか。さてそんなブランチ作成ですが、作成に失敗した経験はありますか?
たとえば次のようにブランチを作ってみます。何の問題もありません。
$ git switch -c feature/aaa/bbb Switched to a new branch 'feature/aaa/bbb'
ところがある環境だとこのコマンドは失敗します。具体的には次のようなエラーメッセージが出ます。
$ git switch -c feature/aaa/bbb fatal: cannot lock ref 'refs/heads/feature/aaa/bbb': 'refs/heads/feature/aaa' exists; cannot create 'refs/heads/feature/aaa/bbb'
ちなみにすでに存在するブランチ名で作成しようとすると次のようなメッセージが出ます。そのため上記のエラーはこれとは原因が異なります。
$ git switch -c feature/aaa fatal: a branch named 'feature/aaa' already exists
今回の原因
このエラーを再現するには、まずfeature/aaa
ブランチを作成し、その後でfeature/aaa/bbb
ブランチを作成しようとします。
$ git switch -c feature/aaa Switched to a new branch 'feature/aaa' $ git switch -c feature/aaa/bbb fatal: cannot lock ref 'refs/heads/feature/aaa/bbb': 'refs/heads/feature/aaa' exists; cannot create 'refs/heads/feature/aaa/bbb'
Gitではfeature/aaa
のようにブランチ名に /
が含まれている場合、内部的にrefs/heads/
の下に同名のディレクトリを作成します。
実際に確認してみると、たしかにディレクトリが作成されています。
$ ls .git/refs/heads/* .git/refs/heads/main .git/refs/heads/feature: aaa
さてこの状態でfeature/aaa/bbb
ブランチを作成しようとすると、やはりディレクトリを作成しようとしますが、すでに存在します。Gitでは、このケースではエラーとなってしまいます。
対応策
前提としてすでにfeature/aaa
ブランチが存在するのであれば、接頭辞としてfeature/aaa/
は使用できません。しかしブランチの派生元として、わかりやすい名前にしたいという場合もあるでしょう。そこで、私の場合はfeature/aaa__bbb
のようなブランチ名にすることで解決しています。
まとめ
あまりブランチの作成でエラーになることはないので、はじめて目にするとびっくりしてしまいますね。原因を知っていれば対処は難しくありません。普段から運用しやすい命名規則を作っておくとよいですね。